package ui;

import io.Feed;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;

/**
 * Clase que representa un Modelo custom para manejar los datos de una tabla de
 * feeds. Implementa la interfaz TableModel
 *
 * @author Nicolás Garay
 * @author Alejandro Jacquet
 * @author Rita Romani
 */
public class ModeloTablaFeeds implements TableModel {

    /** Atributo que representa los datos del modelo. */
    private List<Feed> datos = new ArrayList();
    /** Atributo que representa los oyentes al modelo. */
    private ArrayList suscriptores = new ArrayList();
    /** Atributo que representa la cantidad de columnas. */
    private int cantidadDeColumnas;

    /**
     * Constructor del modelo.
     */
    public ModeloTablaFeeds() {
        cantidadDeColumnas = 3;
        
    }

    /**
     * Método público para agregar un oyente.
     *
     * @param listen TableModelListener oyente
     */
    @Override
    public void addTableModelListener(TableModelListener listen) {
        suscriptores.add(listen);
    }

    /**
     * Método público para remover un oyente.
     *
     * @param listen TableModelListener oyente
     */
    @Override
    public void removeTableModelListener(TableModelListener listen) {
        suscriptores.remove(listen);
    }

    /**
     * Método público que devuelve el número de columnas del modelo.
     *
     * @return int cantidad de columnas
     */
    @Override
    public int getColumnCount() {
        return cantidadDeColumnas;
    }

    /**
     * Método público que devuelve el número de filas del modelo.
     *
     * @return int cantidad de filas
     */
    @Override
    public int getRowCount() {
        // Devuelve el tamaño de la lista datos en el modelo, es decir, el número de filas en la tabla
        return datos.size();
    }

    /**
     * Método público que devuelve la clase de un número de columna pasado como
     * parámetro.
     *
     * @param columna int número de columna
     * @return Class de la columna
     */
    @Override
    public Class getColumnClass(int columna) {
        switch (columna) {
            case 0: {
                return String.class;
            }
            case 1: {
                return String.class;
            }
            case 2: {
                return String.class;
            }
        }
        return String.class;
    }

    /**
     * Método público que devuelve el nombre de un número de columna pasado como
     * parámetro.
     *
     * @param columna int número de columna
     * @return String nombre de la clase
     */
    @Override
    public String getColumnName(int columna) {
        switch (columna) {
            case 0: {
                return "Título";
            }
            case 1: {
                return "Fecha de Publicación";
            }
            case 2: {
                return "Autor";
            }
        }
        return "";
    }

    /**
     * Método público que devuelve un valor boolean, de acuerdo a si la celda
     * (fila-columna) es editable o no. Ninguna celda es editable.
     *
     * @param rowIndex int fila
     * @param columnIndex int columna
     * @return boolean (false)
     */
    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
    }

    /**
     * Método público que permite insertar un dato en una celda. No implementa
     * funcionalidad.
     *
     * @param dato
     * @param fila
     * @param columna
     */
    @Override
    public void setValueAt(Object dato, int fila, int columna) {
    }

    /**
     * Método público que obtiene el dato correspondiente a una celda
     * (fila-columna) pasada como parámetro.
     *
     * @param fila int
     * @param columna int
     * @return Object dato correspondiente
     */
    @Override
    public Object getValueAt(int fila, int columna) {
        Feed feed = datos.get(fila);
        switch (columna) {
            case 0: {
                return feed.getTitulo();
            }
            case 1: {
                // Formateamos la fecha de publicación del feed
                SimpleDateFormat formateador = new SimpleDateFormat("dd-MM-yyyy   h:m a");
                return formateador.format(feed.getFechaPublicacion());
            }
            case 2: {
                return feed.getAutor();
            }
        }
        return null;
    }

    /**
     * Método público que permite asignar a la lista "datos" del modelo una
     * lista pasada como parámetro.
     *
     * @param listaFeeds List<Feed>
     */
    public void setListaFeeds(List<Feed> listaFeeds) {
        datos = listaFeeds;
        // Avisa a los suscriptores creando un TableModelEvent...
        TableModelEvent evento;
        evento = new TableModelEvent(this, this.getRowCount() - 1, this.getRowCount() - 1,
                TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT);
        // ... y avisando a los suscriptores
        int i;
        for (i = 0; i < suscriptores.size(); i++) {
            ((TableModelListener) suscriptores.get(i)).tableChanged(evento);
        }
    }

    /**
     * Método público que devuelve el objeto Feed correspondiente a una fila
     * pasada como parámetro.
     *
     * @param fila int
     * @return Feed
     */
    public Feed getFeed(int fila) {
        return datos.get(fila);
    }

    /**
     * Método público que asigna a la lista "datos" un nuevo ArrayList, de esta
     * forma se borran todos los datos del modelo.
     *
     */
    public void eliminarDatos() {
        datos = new ArrayList();
        // Avisa a los suscriptores creando un TableModelEvent...
        TableModelEvent evento;
        evento = new TableModelEvent(this, this.getRowCount() - 1, this.getRowCount() - 1,
                TableModelEvent.ALL_COLUMNS, TableModelEvent.DELETE);
        // ... y avisando a los suscriptores
        int i;
        for (i = 0; i < suscriptores.size(); i++) {
            ((TableModelListener) suscriptores.get(i)).tableChanged(evento);
        }
    }
}
